package com.plumecache.core;

import com.plumecache.core.exception.PlumeCacheException;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.redisnode.RedisNode;
import org.redisson.api.redisnode.RedisNodes;
import org.redisson.api.redisnode.RedisSentinelMasterSlave;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;

import java.util.Arrays;
import java.util.Map;

public class SentinelRedisCacheService extends RedisCacheService {

    @Override
    public void initialize(InstanceProperties properties) {
        super.initialize(properties);

        String endpoint = properties.getEndpoint();
        if (StringUtils.isEmpty(endpoint)) {
            throw new PlumeCacheException("can't find [endpoint] properties");
        }

        String[] nodeAddressArray = Arrays.stream(endpoint.split(",")).map(r -> "redis://" + r).toArray(String[]::new);
        Config config = new Config();

        SentinelServersConfig sentinelServersConfig = config.useSentinelServers()
                .setMasterName("plume-cache-master")
                .addSentinelAddress(nodeAddressArray);

        if (StringUtils.isNotBlank(properties.getUsername())) {
            sentinelServersConfig.setUsername(properties.getUsername());
        }

        if (StringUtils.isNotBlank(properties.getPassword())) {
            sentinelServersConfig.setPassword(properties.getPassword());
        }

        if (StringUtils.isNotBlank(properties.getTimeout())) {
            sentinelServersConfig.setTimeout(Integer.parseInt(properties.getTimeout()));
        }

        if (StringUtils.isNotBlank(properties.getConnectTimeout())) {
            sentinelServersConfig.setConnectTimeout(Integer.parseInt(properties.getConnectTimeout()));
        }

        if (StringUtils.isNotBlank(properties.getConnectionPoolSize())) {
            sentinelServersConfig.setMasterConnectionPoolSize(Integer.parseInt(properties.getConnectionPoolSize()));
            sentinelServersConfig.setSlaveConnectionPoolSize(Integer.parseInt(properties.getConnectionPoolSize()));
        }


        redissonClient = Redisson.create(config);
    }

    @SneakyThrows
    @Override
    public Map<String, String> getStatistics() {
        RedisSentinelMasterSlave redisNodes = redissonClient.getRedisNodes(RedisNodes.SENTINEL_MASTER_SLAVE);
        return redisNodes.getSentinels().stream().findFirst().get().info(RedisNode.InfoSection.ALL);
    }
}
